# 安装Selenium套件
# pip install selenium
#
# 安裝WebDriver
# 可以去这裡下载WebDriver，注意要与你的Chrome浏览器版本相同。下载并解压缩后会得到一个chromedriver.exe的可执行档，建议将这个档案複製到你的Python项目资料夹下，可以避免路径的问题。
#
# 01. 浏览网页
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

service = Service('./chromedriver')  # 设定chromedriver路径
driver = webdriver.Chrome(service=service)
driver.get('https://www.baidu.com')  # 浏览百度网站首页
print(driver.title)  # 百度一下，你就知道

# 02. 查找单一元素
"""
<html>
 <body>
  <form id="loginForm">
   <input name="username" type="text" />
   <input name="password" type="password" />
   <input name="continue" type="submit" value="Login" />
  </form>
 </body>
</html>
"""

login_form = driver.find_element(By.ID, 'loginForm')  # 用ID查找
username = driver.find_element(By.NAME, 'username')  # 用NAME查找
username = driver.find_element(By.XPATH, "//input[@name='username']")  # 用 XPATH 查找
"""
<html>
 <body>
  <h2>Welcome!</h2>
  <p class="content">Are you a stranger here?</p>
  <a href="continue.html">Continue</a>  
  <a href="cancel.html">Cancel</a>
 </body>
</html>
"""

continue_link = driver.find_element(By.LINK_TEXT, 'Continue')  # 用超链接文本查找
continue_link = driver.find_element(By.PARTIAL_LINK_TEXT, 'Cont')  # 用部分超链接文本查找
heading = driver.find_element(By.TAG_NAME, 'h2')  # 用标签名称查找
content = driver.find_element(By.CLASS_NAME, 'content')  # 用Class名称查找
content = driver.find_element(By.CSS_SELECTOR, 'p.content')  # 用CSS选择器查找

# 03. 查找多个元素
# 查找多个元素返回值将会是一个列表(list)。

login_form = driver.find_elements(By.ID, 'loginForm')  # 用ID查找
username = driver.find_elements(By.NAME, 'username')  # 用NAME查找
username = driver.find_elements(By.XPATH, "//input[@name='username']")  # 用XPATH查找
continue_link = driver.find_elements(By.LINK_TEXT, 'Continue')  # 用超链接查找
continue_link = driver.find_elements(By.PARTIAL_LINK_TEXT, 'Cont')  # 用部分超链接查找
heading = driver.find_elements(By.TAG_NAME, 'h2')  # 用标签名称查找
content = driver.find_elements(By.CLASS_NAME, 'content')  # 用Class名称查找
content = driver.find_elements(By.CSS_SELECTOR, 'p.content')  # 用CSS选择器查找

# 04. 属性值
attribute_value = element.get_attribute('attribute-name')  # 取得"attribute-name"的属性值"attribute_value"

# 05. 预期条件
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.ID, 'my-element-id')))  # 最多等待10秒让元素变为可见
elements = wait.until(EC.visibility_of_all_elements_located((By.CLASS_NAME, 'my-class')))  # 最多等待10秒，让所有元素都可见

# 06. 等待
# 显式等待
# 显式等待用于指示 webdriver 在移动到自动化脚本中的其他步骤之前等待特定条件。

from selenium.webdriver.support import expected_conditions as EC

# expected_conditions模块用于指定要等待的条件

driver.get("https://www.example.com")

element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "example-id")))
# WebDriverWait方法用于指定驱动程序和等待的最长时间，本例中一旦找到元素并可点击，脚本就会继续执行。
element.click()

# 07. 隐式等待
# 隐式等待是被应用在尝试识别当前不可用的元素时，指示 webdriver 在特定时间内轮询 DOM（文档对象模型）。

driver.implicitly_wait(10)  # 设定隐式等待10秒
driver.get("https://www.example.com")
element = driver.find_element_by_id("example-id")
# 在此示例中，为Web驱动程序的整个生命周期设置了10秒的隐式等待。这意味着如果未找到元素，驱动程序将等待最多10秒然后抛出异常。如果在10秒内找到元素，脚本将继续执行。
# 单选按钮&复选框
radio_button.click()  # 选择单选按钮
if not checkbox.is_selected():
    checkbox.click()  # 选中或取消选中复选框

# 08. 下拉列表
# 选择下拉列表中的选项
dropdown.select_by_visible_text("Option 1")
# 或者 dropdown.select_by_value("value_1")
# 或者 dropdown.select_by_index(0)

"""
 需要注意的是，如果下拉列表不允许多选，则只能选择一个选项。如果下拉列表允许多选，则可以使用select_by_visible_text、select_by_value或select_by_index方法选择多个选项。如果想取消选中已选择的选项，可以使用deselect_by_visible_text、deselect_by_value或deselect_by_index方法来取消选择。如果想取消选择所有选项，则可以使用deselect_all方法。
"""
# 09. Cookies
driver.get("https://www.example.com")

cookie = {'name': 'example_cookie', 'value': '1234'}
driver.add_cookie(cookie)  # 给浏览器增加一个Cookie

example_cookie = driver.get_cookie('example_cookie')  # 以Cookie的名称取得Cookie
print(example_cookie)

cookies = driver.get_cookies()  # 从浏览器取得所有Cookie
print(cookies)

driver.delete_cookie('example_cookie')  # 以Cookie的名称删除Cookie

driver.delete_all_cookies()  # 删除所有的Cookie

driver.refresh()  # 刷新网页

# 10. 前后浏览
driver.get('https://www.baidu.com')
driver.get('https://world.taobao.com')
driver.back()  # 向后浏览（回退）
print(driver.title)  # 百度一下，你就知道
driver.forward()  # 向前浏览（前进）
print(driver.title)  # Taobao | 淘宝 - 花更少淘到宝

# 11. 动作链
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

action = ActionChains(driver)
action.move_to_element(element).click().perform()  # 移至element并点击
action.context_click(element).perform()  # 移至element并以右键点击

action.drag_and_drop(source_element, target_element).perform()  # 将source_element拖放到target_element

action.click(element).perform()  # 点击element
action.double_click(element).perform()  # 双击element

action.key_down(Keys.CONTROL).send_keys("s").perform()  # 按下"Ctrl+S"

action.send_keys("Hello, world!").perform()  # 在当前文字框输入"Hello, world!"
action.send_keys_to_element(element, "Hello, world!").perform()  # 在element文字框输入"Hello, world!"
action.send_keys_to_element(element, Keys.ENTER).perform()  # 在element文字框输入"ENTER"

# 12. 表单
driver.get('https://www.baidu.com')
driver.find_element(By.ID, 'kw').send_keys('Python')  # 在文字框输入"Python"
driver.find_element(By.ID, 'su').submit()  # 提交表单

# 13. 滚动
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")  # 滚动至页面底部
driver.execute_script("window.scrollBy(0, 500)")  # 将页面向下滚动500像素
# 框架
driver.switch_to.frame("my-frame")  # 通过名称或ID 切换 到框架"my-frame"

element = driver.find_element(By.CSS_SELECTOR, "div.my-element")
print(element.text)

driver.switch_to.default_content()  # 切换回主框架

# 14. JavaScript
driver.execute_script("alert('Hello, world!');")  # 执行JavaScript

# 15. 窗口
driver = webdriver.Chrome()  # 创建一个浏览器实例

driver.execute_script("window.open('');")  # 打开一个新的窗口

handles = driver.window_handles  # 获取所有窗口句柄

driver.switch_to.window(handles[-1])  # 切换到新窗口

driver.get("https://www.google.com")

# 在新窗口中搜索内容
search_box = driver.find_element_by_name("q")
search_box.send_keys("Selenium")
search_box.send_keys(Keys.RETURN)

driver.close()  # 关闭当前窗口

driver.switch_to.window(handles[0])  # 切换回原始窗口

# 截图
driver.save_screenshot('logo.png')

# 无头浏览器
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True

driver = webdriver.Chrome(options=options)


# 如何实现让 selenium 规避被检测到的风险
bro = webdriver.Chrome(executable_path='./driver_path', chrome_options=chrome_options)


# 关闭
driver.close()  # 关闭当前窗口
driver.quit()  # 关闭浏览器
